package cn.tedu.hotel.serve.service.impl;

import cn.tedu.hotel.serve.ex.ServiceException;
import cn.tedu.hotel.serve.mapper.HotelMapper;
import cn.tedu.hotel.serve.mapper.HotelScoreMapper;
import cn.tedu.hotel.serve.pojo.dto.HotelDTO;
import cn.tedu.hotel.serve.pojo.dto.HotelRoomInfoDTO;
import cn.tedu.hotel.serve.pojo.dto.HotelUpdateDTO;
import cn.tedu.hotel.serve.pojo.entity.Hotel;
import cn.tedu.hotel.serve.pojo.entity.HotelRoomInfo;
import cn.tedu.hotel.serve.pojo.vo.*;
import cn.tedu.hotel.serve.service.IHotelService;
import cn.tedu.hotel.serve.web.ServiceCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class HotelServiceImpl implements IHotelService {

    @Value("${dirPath}")
    private String dirPath;

    @Autowired
    HotelMapper hotelMapper;

    @Autowired
    HotelScoreMapper hotelScoreMapper;

    @Override
    public void addHotelInfo(HotelDTO hotelDTO) {
        log.debug("开始处理【后台添加酒店】的业务，参数：{}",hotelDTO);
        int count = hotelMapper.countByName(hotelDTO.getName());
        if (count>0){
            String message = "添加酒店失败，酒店名字已存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }
        count = hotelMapper.countByLocation(hotelDTO.getLocation());
        if (count>0){
            String message = "添加酒店失败，酒店地址已存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }
        /*查询酒店星级服务*/
        HotelLevelVO hotelLevel = hotelMapper.getByHotelLevelId(hotelDTO.getLevelId());
        if (hotelLevel==null){
            String message = "添加酒店失败，星级类型不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }
        /*调用Mapper往hotel表里插入数据*/
        Hotel hotel=new Hotel();
        BeanUtils.copyProperties(hotelDTO,hotel);
        int rows=hotelMapper.addHotelInfo(hotel);
        log.debug("往hotel表里面插入了数据，参数为：{}",hotel);
        if (rows!=1){
            String message = "添加酒店失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_INSERT, message);
        }

        /*往hotel_room_info插入房间数量的数据和酒店房间的价格*/
        List<HotelRoomInfo> hotelRoomInfoList=new ArrayList<>();
        List<RoomVO> roomList = hotelMapper.getRoomList();
        for (RoomVO roomVO : roomList) {
            HotelRoomInfo hotelRoomInfo=new HotelRoomInfo();
            hotelRoomInfo.setHotelId(hotel.getId());
            hotelRoomInfo.setHotelName(hotel.getName());
            hotelRoomInfo.setRoomName(roomVO.getName());
            hotelRoomInfo.setRoomId(roomVO.getId());
            hotelRoomInfo.setNumber(HOTEL_ROOM_NUMBER);
            /*BigDecimal是不允许直接使用运算符号的，需要加上方法来进行加减乘除*/
            BigDecimal roomPrice=hotel.getBasePrice().add(roomVO.getPrice().multiply(hotelLevel.getSold()));
            hotelRoomInfo.setPrice(roomPrice);
            hotelRoomInfoList.add(hotelRoomInfo);
        }
        rows=hotelMapper.addHotelRoomInfoBatch(hotelRoomInfoList);
        log.debug("往hotel_room_info表里面插入了数据，参数为：{}",hotelRoomInfoList);
        if (rows!=roomList.size()){
            String message = "添加酒店失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_INSERT, message);
        }
    }

    @Override
    public List<HotelVO> getHotelList() {
        log.debug("开始处理【后台查询酒店】的业务");
        List<HotelVO> hotelList = hotelMapper.getHotelList();
        log.debug("查询酒店的所有信息：{}",hotelList);
        return hotelList;
    }

    @Override
    public List<HotelLevelVO> getHotelLevelList() {
        log.debug("开始处理【后台查询酒店星级】的业务");
        List<HotelLevelVO> hotelLevelList = hotelMapper.getHotelLevelList();
        log.debug("查询酒店星级的所有信息：{}",hotelLevelList);
        return hotelLevelList;
    }

    @Override
    public List<HotelSearchVO> getHotelListBySomethingOfLocation(String location) {
        log.debug("开始处理【前台酒店查询】的业务");
        List<HotelSearchVO> hotelSearchVOList=new ArrayList<>();
        List<HotelVO> hotelListBySomethingOfLocation = hotelMapper.getHotelListBySomethingOfLocation(location);
        for (HotelVO hotelVO : hotelListBySomethingOfLocation) {
            HotelSearchVO hotelSearchVO=new HotelSearchVO();
            HotelLevelVO hotelLevelVO = hotelMapper.getByHotelLevelId(hotelVO.getLevelId());
            String type = hotelLevelVO.getType();
            BigDecimal hotelAvgScore = getHotelAvgScore(hotelVO.getId());
            BeanUtils.copyProperties(hotelVO,hotelSearchVO);
            hotelSearchVO.setType(type);
            hotelSearchVO.setAvgScore(hotelAvgScore);
            hotelSearchVOList.add(hotelSearchVO);
        }
        log.debug("前台模糊查询酒店参数：{}",hotelSearchVOList);
        return hotelSearchVOList;
    }

    @Override
    public List<HotelSearchVO> getHotelListByContent(String content) {
        log.debug("开始处理【前台用户输入数据查询酒店】的业务");
        List<HotelSearchVO> hotelSearchVOList=new ArrayList<>();
        List<HotelVO> hotelListByContent = hotelMapper.getHotelListByContent(content);
        for (HotelVO hotelVO : hotelListByContent) {
            HotelSearchVO hotelSearchVO=new HotelSearchVO();
            HotelLevelVO hotelLevelVO = hotelMapper.getByHotelLevelId(hotelVO.getLevelId());
            String type = hotelLevelVO.getType();
            BigDecimal hotelAvgScore = getHotelAvgScore(hotelVO.getId());
            BeanUtils.copyProperties(hotelVO,hotelSearchVO);
            hotelSearchVO.setType(type);
            hotelSearchVO.setAvgScore(hotelAvgScore);
            hotelSearchVOList.add(hotelSearchVO);
        }
        log.debug("前台用户输入数据查询酒店参数：{}",hotelSearchVOList);
        return hotelSearchVOList;
    }

    @Override
    public BigDecimal getHotelAvgScore(Long hotelId) {
        log.debug("开始处理【前台展示酒店平均分数】的业务，参数：{}",hotelId);
        HotelStandardVO hotelStandardVO = hotelMapper.getHotelById(hotelId);
        if (hotelStandardVO==null){
            String message = "酒店不存在，请稍后重试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }
        List<HotelScoreVO> list = hotelScoreMapper.getHotelScoreListByHotelId(hotelId);
        log.debug("返回的参数：{}",list);
        if (list.isEmpty()){
            BigDecimal avgScore=new BigDecimal(Double.toString(BASE_SCORE));
            avgScore=avgScore.setScale(1);
            return avgScore;
        }
        BigDecimal avgScore = hotelScoreMapper.getHotelAvgScoreByHotelId(hotelId);
        avgScore=avgScore.setScale(1,BigDecimal.ROUND_UP);
        return avgScore;
    }

    @Override
    public HotelLevelVO getByHotelLevelId(Long id) {
        log.debug("开始处理【前台根据酒店ID{}，查询酒店等级】的业务",id);
        HotelLevelVO hotelLevelVO = hotelMapper.getByHotelLevelId(id);
        log.debug("前台根据酒店ID{}，查询酒店等级{}",id,hotelLevelVO);
        return hotelLevelVO;
    }

    @Override
    public void delete(Long id) {
        log.debug("HotelService开始处理[根据ID删除主题相册的业务],参数{}", id);
        HotelStandardVO hotelStandardVO = hotelMapper.getHotelById(id);

        log.debug("根据ID={}检查主题相册数据是否存在，查询结果：{}", id, hotelStandardVO);

        //判断是否存在
        if (hotelStandardVO == null) {
            //是,抛出异常
            String message = "删除酒店失败，尝试删除的酒店数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }
        // 调用Mapper对象的deleteById()方法执行删除
        log.debug("即将执行删除，参数：{}", id);

        String url = hotelStandardVO.getUrl();
        log.debug("图片路径:" + dirPath + url);
        new File(dirPath + url).delete();

        hotelMapper.deleteById(id);
    }

    @Override
    public HotelStandardVO getHotelById(Long id) {
        log.debug("开始处理【前台根据酒店ID{}，查询酒店】的业务",id);
        HotelStandardVO hotelStandardVO = hotelMapper.getHotelById(id);
        if (hotelStandardVO==null){
            String message = "查询酒店失败，查询的酒店数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }
        log.debug("酒店的信息：{}",hotelStandardVO);
        return hotelStandardVO;
    }

    @Override
    public HotelStandardVO getAdminHotelById(Long id) {
        log.debug("开始处理【后台根据酒店ID{}，删除酒店】的业务",id);
        return hotelMapper.getHotelById(id);
    }

    @Override
    public void update(Long id, HotelUpdateDTO hotelUpdateDTO) {
        HotelStandardVO hotelStandardVO = hotelMapper.getHotelById(id);
        log.debug("根据ID={}检查酒店数据是否存在，查询结果：{}", id, hotelStandardVO);
        //判断是否存在
        if (hotelStandardVO == null) {
            //是,抛出异常
            String message = "修改酒店失败，尝试修改的酒店数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }
        // 调用Mapper对象的update()方法执行修改
        log.debug("即将执行修改，参数：{}", id);
        log.debug("hotelStandardVO的url：{}", hotelUpdateDTO.getUrl());
        Hotel hotel = new Hotel();
        BeanUtils.copyProperties(hotelUpdateDTO,hotel);
        hotel.setId(id);
        log.debug("url:{}", hotel.getUrl());
        hotelMapper.update(hotel);
    }

    @Override
    public List<HotelRoomInfoVO> getAdminHotelRoomInfoList() {
        log.debug("开始处理【后台获取酒店房间信息列表】的业务");
        List<HotelRoomInfoVO> list = hotelMapper.getAdminHotelRoomInfoList();
        return list;
    }

    @Override
    public void deleteHotelRoomInfo(Long id) {
        log.debug("开始处理【后台根据酒店房间信息ID：{}删除数据】的业务",id);
        HotelRoomInfoVO hotelRoomInfoVO = hotelMapper.getAdminHotelRoomInfoById(id);
        if (hotelRoomInfoVO==null){
            String message = "数据不存在，请稍后重试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }
        int rows = hotelMapper.deleteHotelRoomInfo(id);
        if (rows!=1){
            String message = "服务器繁忙，请稍后重试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_DELETE, message);
        }
    }

    @Override
    public HotelRoomInfoVO getAdminHotelRoomInfoById(Long id) {
        log.debug("开始处理【后台根据酒店房间信息ID：{}查询酒店房间信息】的业务",id);
        HotelRoomInfoVO hotelRoomInfoVO = hotelMapper.getAdminHotelRoomInfoById(id);
        log.debug("开始处理【后台根据酒店房间信息ID：{}查询酒店房间信息:{}】的业务",id,hotelRoomInfoVO);
        return hotelRoomInfoVO;
    }

    @Override
    public void updateAdminHotelRoomInfoById(Long id, HotelRoomInfoDTO hotelRoomInfoDTO) {
        log.debug("开始处理【后台根据酒店房间信息ID：{}修改酒店房间信息】的业务",id);
        HotelRoomInfoVO hotelRoomInfoVO = hotelMapper.getAdminHotelRoomInfoById(id);
        if (hotelRoomInfoVO==null){
            String message = "数据不存在，请稍后重试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }
        HotelRoomInfo hotelRoomInfo=new HotelRoomInfo();
        BeanUtils.copyProperties(hotelRoomInfoDTO,hotelRoomInfo);
        hotelRoomInfo.setId(id);

        int rows = hotelMapper.updateAdminHotelRoomInfoById(hotelRoomInfo);
        if (rows!=1){
            String message = "服务器繁忙，请稍后重试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_UPDATE, message);
        }
    }

    @Override
    public void addAdminHotelRoomInfo(HotelRoomInfoDTO hotelRoomInfoDTO) {
        log.debug("开始处理【后台添加酒店房间信息】的业务，参数：{}",hotelRoomInfoDTO);
        HotelStandardVO hotelStandardVO = hotelMapper.getHotelById(hotelRoomInfoDTO.getHotelId());
        if (hotelStandardVO==null){
            String message = "酒店不存在，请稍后重试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }
        HotelRoomInfo hotelRoomInfo=new HotelRoomInfo();
        BeanUtils.copyProperties(hotelRoomInfoDTO,hotelRoomInfo);
        List<HotelRoomInfoVO> list =
                hotelMapper.getHotelRoomInfoByHotelId(hotelRoomInfoDTO.getHotelId());
        hotelRoomInfo.setRoomId(list.size()+1L);
        int rows = hotelMapper.addAdminHotelRoomInfo(hotelRoomInfo);
        if (rows!=1){
            String message = "服务器繁忙，请稍后重试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_INSERT, message);
        }
    }
}
